﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace xboxssbeatemup
{
    public class Shader
    {

        public Effect effect;
        public String[] shaders;

        public Shader(params String[] shaderPaths)
        {
            shaders = new String[shaderPaths.Length];
            for (int i = 0; i < shaderPaths.Length; i++)
            {
                shaders[i] = shaderPaths[i];
            }
        }

        public void Initialize(Game game)
        {
            for (int i = 0; i < shaders.Length; i++)
            {
                effect = game.Content.Load<Effect>(/*"FX\\" + */shaders[i]);
            }
            game.GraphicsDevice.VertexDeclaration = new VertexDeclaration(game.GraphicsDevice, VertexPositionNormalTexture.VertexElements);
        }

        public void DrawGameObject(Game game, CameraComponent camera, GameObject gameObject)
        {
            Matrix matWorld = Matrix.Identity *
                Matrix.CreateFromYawPitchRoll(
                        gameObject.modelRotation.Y,
                        gameObject.modelRotation.X,
                        gameObject.modelRotation.Z) *
                        Matrix.CreateTranslation(gameObject.modelPosition) *
                        Matrix.CreateFromYawPitchRoll(
                        gameObject.rotation.Y,
                        gameObject.rotation.X,
                        gameObject.rotation.Z) *
                        Matrix.CreateScale(gameObject.scale) *
                        Matrix.CreateTranslation(gameObject.position);
            Matrix matWorldViewProj = matWorld *
                camera.View *
                camera.Projection;
            for (int i = 0; i < shaders.Length; i++)
            {
                effect.CurrentTechnique = effect.Techniques[0];

                effect.Begin();
                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    foreach (ModelMesh mesh in gameObject.model.Meshes)
                    {
                        foreach (ModelMeshPart part in mesh.MeshParts)
                        {
                            //worldMatrix = bones[mesh.ParentBone.Index] * renderMatrix;

                            if (effect.Parameters["matWorldViewProj"] != null)
                                effect.Parameters["matWorldViewProj"].SetValue(matWorldViewProj);
                            if (effect.Parameters["matWorld"] != null)
                                effect.Parameters["matWorld"].SetValue(matWorld);
                            if (effect.Parameters["vLightDirection"] != null)
                                effect.Parameters["vLightDirection"].SetValue(new Vector4(0.0f,0.0f,1.0f,1.0f));
                            Vector4 vecEye = 
                                new Vector4(camera.LookAt,1.0f);
                            Vector4 vColorDiffuse = new Vector4(0.3f, 0.3f, 0.7f, 1.0f);
                            Vector4 vColorSpecular = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
                            Vector4 vColorAmbient = new Vector4(0.1f, 0.1f, 0.1f, 1.0f);


                            // .. and pass it into our shader.
                            // To access a parameter defined in our shader file ( Shader.fx ), use effectObject.Parameters["variableName"]
                            //Matrix worldInverse = Matrix.Invert(worldMatrix);
                            Vector4 vLightDirection = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);
                            if (effect.Parameters["vecEye"] != null)
                                effect.Parameters["vecEye"].SetValue(vecEye);
                            if (effect.Parameters["vDiffuseColor"] != null)
                                effect.Parameters["vDiffuseColor"].SetValue(vColorDiffuse);
                            if (effect.Parameters["vSpecularColor"] != null)
                                effect.Parameters["vSpecularColor"].SetValue(vColorSpecular);
                            if (effect.Parameters["vAmbient"] != null)
                                effect.Parameters["vAmbient"].SetValue(vColorAmbient);
                            if (effect.Parameters["g_fTime"] != null)
                                effect.Parameters["g_fTime"].SetValue(((Game1)game).elapsedGameTime);
                            game.GraphicsDevice.Vertices[0].SetSource(mesh.VertexBuffer, part.StreamOffset, part.VertexStride);
                            game.GraphicsDevice.Indices = mesh.IndexBuffer;
                            game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                                                                          part.BaseVertex, 0, part.NumVertices,
                                                                          part.StartIndex, part.PrimitiveCount);
                        }
                    }
                    pass.End();
                }
                effect.End();
            }
        }


    }
}

